package network

import (
	"gitee.com/amoyx/cloud-provider/pkg/cloud/tencent/models"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
	"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
	tvpc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312"
	"strconv"
)

type EIPGreeter interface {
	EIP(region string) EIPInterface
}

type EIPInterface interface {
	CreateBandWidthPostpaid(in models.EIPRequest) (taskId string, err error) // 创建按带宽后付费实例
	CreateBandWidthPrepaid(in models.EIPRequest) (taskId string, err error)  // 创建按带宽预付费实例
	CreateTraffic(in models.EIPRequest) (taskId string, err error)           //  创建按流量付费实例
	Get(id string) (result models.EIPResponse, err error)
	ListByName(name string) (list []models.EIPResponse, err error)
	ListByIP(ip string) (result models.EIPResponse, err error)
	List() (list []models.EIPResponse, err error)
}

type eip struct {
	network *Network
	region  string
	client  *tvpc.Client
}

func newEIP(network *Network, region string) EIPInterface {
	v := &eip{
		network: network,
		region:  region,
	}
	cpf := profile.NewClientProfile()
	cpf.HttpProfile.Endpoint = string(VpcEndPoint)
	client, _ := tvpc.NewClient(v.network.Credential(), v.region, cpf)
	v.client = client
	return v
}

// CreateBandWidthPostpaid 创建按带宽后付费实例
func (e *eip) CreateBandWidthPostpaid(in models.EIPRequest) (taskId string, err error) {
	return e.allocate("BANDWIDTH_POSTPAID_BY_HOUR", in)
}

// CreateBandWidthPrepaid 创建按带宽预付费实例
func (e *eip) CreateBandWidthPrepaid(in models.EIPRequest) (taskId string, err error) {
	return e.allocate("BANDWIDTH_PREPAID_BY_MONTH", in)
}

// CreateTraffic 创建按流量付费实例
func (e *eip) CreateTraffic(in models.EIPRequest) (taskId string, err error) {
	return e.allocate("TRAFFIC_POSTPAID_BY_HOUR", in)
}

func (e *eip) allocate(chargeType string, in models.EIPRequest) (taskId string, err error) {
	request := tvpc.NewAllocateAddressesRequest()
	request.AddressCount = common.Int64Ptr(in.AddressCount)
	request.AddressName = common.StringPtr(in.AddressName)
	request.InternetChargeType = common.StringPtr(chargeType)
	request.InternetMaxBandwidthOut = common.Int64Ptr(in.InternetMaxBandwidthOut)
	if chargeType == "BANDWIDTH_PREPAID_BY_MONTH" {
		request.AddressChargePrepaid = &tvpc.AddressChargePrepaid{
			Period:        common.Int64Ptr(in.Period),
			AutoRenewFlag: common.Int64Ptr(1),
		}
	}
	response, err := e.client.AllocateAddresses(request)
	if err != nil {
		return
	}
	return *response.Response.TaskId, nil
}

// Get 根据ID获取弹性IP信息
func (e *eip) Get(id string) (result models.EIPResponse, err error) {
	list, err := e.query(map[string]string{"address-id": id})
	if len(list) > 0 {
		return list[0], nil
	}
	return
}

// ListByName 根据名称获取弹性IP信息
func (e *eip) ListByName(name string) (list []models.EIPResponse, err error) {
	list, err = e.query(map[string]string{"address-name": name})
	return
}

// ListByIP 根据IP获取弹性IP信息
func (e *eip) ListByIP(ip string) (result models.EIPResponse, err error) {
	list, err := e.query(map[string]string{"address-ip": ip})
	if len(list) > 0 {
		return list[0], nil
	}
	return
}

// List 获取所有弹性IP列表
func (e *eip) List() (list []models.EIPResponse, err error) {
	return e.query(map[string]string{})
}

func (e *eip) query(args map[string]string) (list []models.EIPResponse, err error) {
	request := tvpc.NewDescribeAddressesRequest()
	var filters []*tvpc.Filter
	for key, val := range args {
		filters = append(filters, &tvpc.Filter{
			Name:   common.StringPtr(key),
			Values: common.StringPtrs([]string{val}),
		})
	}
	request.Offset = common.Int64Ptr(0)
	request.Limit = common.Int64Ptr(100)
	response, err := e.client.DescribeAddresses(request)
	if err != nil {
		return
	}

	for _, row := range response.Response.AddressSet {
		list = append(list, models.EIPResponse{
			AddressId:               *row.AddressId,
			AddressName:             *row.AddressName,
			AddressStatus:           *row.AddressStatus,
			AddressIp:               *row.AddressIp,
			InstanceId:              *row.InstanceId,
			CreatedTime:             *row.CreatedTime,
			NetworkInterfaceId:      *row.NetworkInterfaceId,
			PrivateAddressIp:        *row.PrivateAddressIp,
			IsArrears:               *row.IsArrears,
			IsBlocked:               *row.IsBlocked,
			IsEipDirectConnection:   *row.IsEipDirectConnection,
			AddressType:             *row.AddressType,
			CascadeRelease:          *row.CascadeRelease,
			InternetServiceProvider: *row.InternetServiceProvider,
			LocalBgp:                *row.LocalBgp,
			Bandwidth:               strconv.FormatUint(*row.Bandwidth, 10),
			InternetChargeType:      *row.InternetChargeType,
			DeadlineDate:            *row.DeadlineDate,
			InstanceType:            *row.InstanceType,
			Egress:                  *row.Egress,
			AntiDDoSPackageId:       *row.AntiDDoSPackageId,
		})
	}
	return
}
